<template>
  <el-dialog class="public-dialog" title="批量导入" :modelValue="dialogVisible" align-center :width="1000" @close="handleClose" :close-on-click-modal="false">
    <div class="grid grid-cols-3 py-[6px] h-[100px]">
      <div v-for="item in stepsOpt" :key="item.value" class="flex items-center justify-center">
        <div class="text-[#fff] bg-[var(--base-small-bg-color)] h-[24px] w-[24px] text-center font-bold text-[16px]" :class="item.value == steps ? 'bg-[#3487ff]' : ''">
          {{ item.value }}
        </div>
        <div class="ml-[8px]">{{ item.label }}</div>
      </div>
    </div>

    <div v-if="steps == 1" class="h-[400px]">
      <div class="flex border-[var(--base-border-color)] border-[1px] rounded-[4px] h-[120px] overflow-hidden">
        <div class="w-[120px] bg-[var(--base-small-bg-color)] flex items-center justify-center">
          <div class="dk-iconfont icon-Download" style="font-size: 50px !important"></div>
        </div>
        <div class="flex-1 p-[8px]">
          <div class="text-[16px] mb-[4px] font-bold">填写导入数据信息</div>
          <div class="text-[#666]">请按照数据模板的格式准备导入数据，模板中的表头名称不可更改，表头行不能删除</div>
          <a :href="downloadUrl" class="cursor-pointer">
            <div class="text-[#3366F1] flex items-center gap-1 mt-[4px]">下载模板</div>
          </a>
        </div>
      </div>

      <div class="flex border-[var(--base-border-color)] border-[1px] rounded-[4px] h-[120px] mt-[60px] overflow-hidden" v-loading="loadings.submit">
        <div class="w-[120px] bg-[var(--base-small-bg-color)] flex items-center justify-center">
           <div class="dk-iconfont icon-UploadFilled" style="font-size: 50px !important"></div>
        </div>
        <div class="flex-1 p-[8px]">
          <div class="text-[16px] mb-[4px] font-bold">上传填好的信息表</div>
          <div class="text-[#666]">文件后缀名必须为xls 或xlsx （即Excel格式），文件大小不得大于10M，最多支持导入3000条数据</div>
          <el-upload
            ref="uploadRef"
            v-model:file-list="fileList"
            accept=".csv,.xml,.xlsx"
            class="v-import mt-[4px]"
            :data="extraData"
            :action="ossParams.host ? `${ossParams.host}` : ''"
            :limit="1"
            :auto-upload="false"
            :on-exceed="handleExceed"
            :before-upload="beforeUpload"
          >
            <div class="text-[#3366F1] flex items-center">上传文件</div>
          </el-upload>
        </div>
      </div>
    </div>

    <div v-if="steps == 2">
      <div>
        正常数据：<span class="mr-[16px] text-green">{{ previewData.success_total }}条</span> 异常数据：<span class="text-red">{{ previewData.failed_total }}条</span>
      </div>

      <vxe-grid ref="tableRef" v-bind="tableOptions" :data="previewData.details" class="log-table">
        <template #NO="{ row, rowIndex }">
          <div class="flex items-center">
            <el-tooltip effect="dark" :content="row.failed_reason" placement="right-start" v-if="row.failed_reason">
              <div class="dk-iconfont icon-Warning text-red mr-[4px]"></div>
            </el-tooltip>
            {{ rowIndex + 1 }}
          </div>
        </template>
      </vxe-grid>
    </div>

    <div v-if="steps == 3" class="text-center h-[400px]">
      <div class="dk-iconfont icon-Check text-green mt-[50px]" style="font-size: 50px !important"></div>
      <p class="mb-[16px]">批量导入完成</p>
      <p class="mb-[16px]">
        导入成功：<span class="text-green font-bold">{{ saveData.success_total }}条</span>
      </p>
      <p class="mb-[16px]">
        导入失败：<span class="text-red font-bold">{{ saveData.failed_total }}条</span>
      </p>
      <el-link type="primary" @click="exportToExcel">下载导入结果</el-link>
    </div>

    <template #footer>
      <!-- 第一步 -->
      <template v-if="steps == 1">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" :loading="loadings.submit" :disabled="!fileList.length" @click="submit">下一步</el-button>
      </template>

      <!-- 第二步 -->
      <template v-if="steps == 2">
        <el-button @click="resetUpload">重新上传</el-button>
        <el-button type="primary" :loading="loadings.submit" :disabled="!previewData.details.length" @click="submitSave">导入</el-button>
      </template>

      <!-- 第三步 -->
      <template v-if="steps == 3">
        <el-button @click="resetUpload">重新上传</el-button>
        <el-button type="primary" @click="handleClose(1)">关闭</el-button>
      </template>
    </template>
  </el-dialog>
</template>

<script setup>
import * as XLSX from "xlsx"
import { ElMessage, ElMessageBox, genFileId, ElNotification } from "element-plus"
import { ref } from "vue"
const dialogVisible = ref(false)
const props = defineProps({
  modelValue: { type: Boolean, default: "" },
  callBack: {
    type: Function,
    default: (query) => query,
  },
  querForm: {
    // 查询条件
    type: Object,
    default: () => {},
  },
  importApi: {
    // 导入
    type: Function,
    default: () => {},
  },
  templateApi: {
    // 导入模版下载
    type: Function,
    default: () => {},
  },
  templateApiParams: {
    // 导入模版下载 参数
    type: Object,
    default: () => {},
  },

  tableColumns: {
    //   // 导入模版配置
    type: Array,
    default: () => [],
  },
  importCheck: {
    // 导入校验
    type: Function,
    default: () => {},
  },
  importResult: {
    // 导入结果下载
    type: Function,
    default: () => {},
  },
  importResultParams: {
    // 导入结果下载 参数
    type: Object,
    default: () => {},
  },
})
const xlsxConfig = ref({})

// 步骤
const steps = ref("1")
const stepsOpt = [
  { label: "上传文件", value: "1" },
  { label: "数据预览", value: "2" },
  { label: "导入数据", value: "3" },
]
// 重新上传  重置数据
const resetUpload = () => {
  steps.value = "1"
  uploadRef?.value?.clearFiles()
  for (const key in extraData.valye) {
    extraData.valye[key] = ""
  }
}

const tableOptions = reactive({
  height: "400px",
  border: "full",
  scrollY: { enabled: true },
  columns: [],
  data: [],
})

let loadings = reactive({})
let ossParams = reactive({
  host: "",
})

const emit = defineEmits(["close", "update:modelValue"])

const fileList = ref([])
const uploadRef = ref()
const extraData = reactive({})
const fileName = ref("")
// 当超出限制
const handleExceed = (files) => {
  uploadRef.value?.clearFiles()
  const file = files[0]
  file.uid = genFileId()
  uploadRef.value?.handleStart(file)
}

const get_suffix = (name) => {
  const pos = name.lastIndexOf(".")
  let suffix = ""
  if (pos != -1) {
    suffix = name.substring(pos)
  }
  return suffix
}

// 读取文件
const readFile = async (file) => {
  return new Promise((resolve, reject) => {
    loadings.upload = true
    try {
      let reader = new FileReader()
      reader.readAsBinaryString(file)
      reader.onload = (ev) => {
        let data = ev.target.result
        let workbook = XLSX.read(data, { type: "binary", cellDates: true })
        const wsname = workbook.SheetNames[0] //取第一张表
        const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname])

        // 判断文件模板
        if (ws.length == 0) {
          ElMessage({ message: "文件不包含任何内容", type: "warning" })
          resolve([])
        }
        // 填充表格
        let details = []
        ws.map(async (item, index) => {
          let obj = {}
          for (let key in item) {
            obj[xlsxConfig.value[key]] = String(item[key]).trim()
          }
          details.push(obj)
        })
        resolve(details)
      }
      reader.onerror = () => {
        ElMessage({ message: "读取失败，请重新选择文件再上传", type: "error" })
        resolve([])
      }
    } catch (e) {
      ElMessage({ message: "e", type: "error" })
      resolve([])
    }
  })
}

const beforeUpload = async (file) => {
  if (file.size > 1024 * 1024 * 1024) {
    ElMessage.warning("上传文件大小不能超过1G")
    return false
  }
  loadings.submit = true
  try {
    let details = await readFile(file)
    // 第二步
    stepsTo2(details)
    loadings.submit = false
    return false
  } catch (err) {
    loadings.submit = false
    return false
  }
}

const previewData = ref({
  success_total: 0,
  failed_total: 0,
  details: [],
})
const stepsTo2 = (details) => {
  steps.value = "2"
  let params = {
    ...props.querForm,
    details,
  }
  props?.importCheck(params).then((res) => {
    previewData.value = res.data
  })
}

// 关闭弹窗
const handleClose = (refresh) => {
  resetUpload()
  loadings.submit = false
  fileList.value = []
  dialogVisible.value = false
  if (refresh == 1) props.callBack()
}

// 导入 预览
const submit = async () => {
  // loadings.submit = true
  try {
    await uploadRef.value.submit()
    // setTimeout(() => {
    //   loadings.submit = false
    // }, 1000)
  } catch (error) {
    loadings.submit = false
  }
}

const saveData = ref({
  success_total: 0,
  failed_total: 0,
})
// 导入数据
const submitSave = () => {
  loadings.submit = true
  let params = {
    ...props.querForm,
    details: previewData.value.details,
  }
  props
    .importApi(params)
    .then((res) => {
      saveData.value = res.data
      steps.value = "3"
    })
    .finally(() => {
      loadings.submit = false
    })
}
import action from "@/utils/action.js"

// 下载导入结果
const exportToExcel = () => {
  props.importResult({ id: saveData.value.id, ...props.importResultParams }).then((res) => {
    action.setGlobalState({
      changeMicoTabsPath: {
        path: "/user/profile",
        type: "push",
      },
    })
  })
}

onMounted(() => {})

// 获取导入模板
const downloadUrl = ref("")
const getTpl = async () => {
  props?.templateApi(props?.templateApiParams).then((res) => {
    downloadUrl.value = res.data.template_url
  })
}

const open = async (params = {}) => {
  getTpl()
  dialogVisible.value = true

  props.tableColumns.forEach((item) => {
    xlsxConfig.value[item.title] = item.field
  })
  tableOptions.columns = [{ title: "序号", width: 160, slots: { default: "NO" } }, ...props.tableColumns]

  // getTpl()
}
defineExpose({
  open,
  handleClose,
})
</script>

<style lang="scss" scoped>
.v-import {
  :deep(.el-upload-list) {
    margin-top: 4px;
  }
}
.font-50 {
  width: 50px;
  height: 50px;
  svg {
    width: 50px;
    height: 50px;
  }
}
</style>
